<template>
  <div class="smart-medical-rag" ref="pageContainer">
    <div class="header">
      <h1>智慧医疗RAG辅助分诊系统</h1>
      <div class="zoom-controls">
        <el-button @click="zoomOut" size="small">缩小</el-button>
        <el-button @click="resetZoom" size="small">100%</el-button>
        <el-button @click="zoomIn" size="small">放大</el-button>
        <el-button @click="resetZoom" size="small">重置</el-button>
      </div>
    </div>

    <div class="main-content">
      <!-- 左侧：患者信息输入 -->
      <div class="input-section">
        <h2>患者信息输入</h2>
        
        <el-form :model="patientData" label-width="120px">
          <el-form-item label="主诉">
            <el-input
              v-model="patientData.chiefComplaint"
              type="textarea"
              :rows="4"
              placeholder="请描述患者的主要症状和不适..."
            />
          </el-form-item>

          <el-form-item label="症状描述">
            <el-input
              v-model="symptomsText"
              type="textarea"
              :rows="3"
              placeholder="详细描述症状表现..."
            />
          </el-form-item>

          <el-form-item label="生理指标">
            <div class="vital-signs">
              <div class="vital-sign-item">
                <label>收缩压/舒张压:</label>
                <el-input v-model="patientData.vitalSigns.bloodPressure" placeholder="如: 120/80" />
                <span>mmHg</span>
              </div>
              
              <div class="vital-sign-item">
                <label>心率:</label>
                <el-input-number v-model="patientData.vitalSigns.heartRate" :min="0" :max="300" />
                <span>次/分</span>
              </div>
              
              <div class="vital-sign-item">
                <label>体温:</label>
                <el-input-number v-model="patientData.vitalSigns.temperature" :min="30" :max="45" :precision="1" />
                <span>°C</span>
              </div>
              
              <div class="vital-sign-item">
                <label>呼吸频率:</label>
                <el-input-number v-model="patientData.vitalSigns.respiratoryRate" :min="0" :max="100" />
                <span>次/分</span>
              </div>
              
              <div class="vital-sign-item">
                <label>血氧饱和度:</label>
                <el-input-number v-model="patientData.vitalSigns.oxygenSaturation" :min="0" :max="100" />
                <span>%</span>
              </div>
            </div>
          </el-form-item>

          <el-form-item label="既往病史">
            <el-input
              v-model="patientData.medicalHistory"
              type="textarea"
              :rows="3"
              placeholder="患者的既往病史、过敏史等..."
            />
          </el-form-item>
        </el-form>

        <el-button 
          type="primary" 
          size="large" 
          @click="submitTriageRequest"
          :loading="isProcessing"
          :disabled="!canSubmit"
        >
          开始分诊分析
        </el-button>
      </div>

      <!-- 右侧：分诊结果 -->
      <div class="result-section">
        <h2>分诊结果</h2>
        
        <div v-if="!triageResult" class="no-result">
          <el-empty description="暂无分诊结果" />
        </div>
        
        <div v-else class="triage-result">
          <el-card class="result-card">
            <template #header>
              <div class="result-header">
                <span>推荐科室: {{ triageResult.recommendation.recommendedDepartment }}</span>
                <el-tag :type="getPriorityType(triageResult.recommendation.priority)">
                  {{ getPriorityText(triageResult.recommendation.priority) }}
                </el-tag>
              </div>
            </template>
            
            <div class="result-content">
              <!-- 警告提示区域 -->
              <div v-if="validationWarning" class="warning-section">
                <el-alert
                  :title="validationWarning"
                  type="warning"
                  :closable="false"
                  show-icon
                >
                  <template #default>
                    <p>系统检测到分诊结果可能存在异常，建议咨询专业医生进行确认。</p>
                  </template>
                </el-alert>
              </div>
              
              <div class="reasoning">
                <h4>分析推理:</h4>
                <p>{{ triageResult.recommendation.reasoning }}</p>
              </div>
              
              <div class="confidence">
                <h4>置信度:</h4>
                <el-progress 
                  :percentage="triageResult.confidence * 100" 
                  :color="getConfidenceColor(triageResult.confidence)"
                />
                <span>{{ (triageResult.confidence * 100).toFixed(1) }}%</span>
              </div>
              
              <div class="guidelines" v-if="triageResult.recommendation.guidelineReferences.length > 0">
                <h4>参考指南:</h4>
                <el-tag 
                  v-for="guideline in triageResult.recommendation.guidelineReferences" 
                  :key="guideline"
                  class="guideline-tag"
                >
                  {{ guideline }}
                </el-tag>
              </div>
              
              <div class="sources" v-if="triageResult.traceabilitySources.length > 0">
                <h4>追溯来源:</h4>
                <ul>
                  <li v-for="source in triageResult.traceabilitySources" :key="source">
                    {{ source }}
                  </li>
                </ul>
              </div>
              
              <div class="processing-info">
                <p><strong>处理时间:</strong> {{ formatTime(triageResult.processingTime) }}</p>
                <p><strong>结果有效性:</strong> 
                  <el-tag :type="triageResult.isValid ? 'success' : 'danger'">
                    {{ triageResult.isValid ? '有效' : '无效' }}
                  </el-tag>
                </p>
              </div>
            </div>
          </el-card>
        </div>
      </div>
    </div>

    <!-- 医生反馈 -->
    <div class="feedback-section">
      <h2>医生反馈</h2>
      <el-form :model="doctorFeedback" label-width="120px">
        <el-form-item label="反馈">
          <el-input
            v-model="doctorFeedback.comment"
            type="textarea"
            :rows="3"
            placeholder="请输入您的专业反馈..."
          />
        </el-form-item>
        
        <el-form-item label="准确性">
          <el-rate
            v-model="doctorFeedback.accuracy"
            :max="5"
            show-text
            :texts="['很差', '较差', '一般', '良好', '优秀']"
          />
        </el-form-item>
        
        <el-form-item>
          <el-button @click="submitDoctorFeedback" type="primary">提交反馈</el-button>
          <el-button @click="resetFeedback">重置</el-button>
        </el-form-item>
      </el-form>
    </div>

    <!-- 系统性能监控 -->
    <div class="metrics-section">
      <h2>系统性能监控</h2>
      <div class="metrics-grid">
        <div class="metric-card">
          <h3>响应时间</h3>
          <p>{{ systemMetrics.responseTime }}ms</p>
        </div>
        <div class="metric-card">
          <h3>处理速度</h3>
          <p>{{ systemMetrics.processingSpeed }} 请求/秒</p>
        </div>
        <div class="metric-card">
          <h3>准确率</h3>
          <p>{{ (systemMetrics.accuracy * 100).toFixed(1) }}%</p>
        </div>
        <div class="metric-card">
          <h3>系统状态</h3>
          <p>{{ systemMetrics.systemStatus }}</p>
        </div>
        <div class="metric-card">
          <h3>内存使用</h3>
          <p>{{ systemMetrics.memoryUsage }}%</p>
        </div>
        <div class="metric-card">
          <h3>CPU使用</h3>
          <p>{{ systemMetrics.cpuUsage }}%</p>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, computed, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import { MedicalRAGService, type TriageRequest, type TriageResult, type DoctorFeedback, type SystemMetrics } from '../services/medicalRAGService'

// 页面缩放
const pageContainer = ref<HTMLElement>()
const pageScale = ref(1)

const zoomIn = () => {
  pageScale.value = Math.min(pageScale.value + 0.1, 2)
  updateZoom()
}

const zoomOut = () => {
  pageScale.value = Math.max(pageScale.value - 0.1, 0.5)
  updateZoom()
}

const resetZoom = () => {
  pageScale.value = 1
  updateZoom()
}

const updateZoom = () => {
  if (pageContainer.value) {
    pageContainer.value.style.transform = `scale(${pageScale.value})`
    pageContainer.value.style.transformOrigin = 'top left'
  }
  localStorage.setItem('ragPageScale', pageScale.value.toString())
}

const initZoom = () => {
  const savedScale = localStorage.getItem('ragPageScale')
  if (savedScale) {
    pageScale.value = parseFloat(savedScale)
    updateZoom()
  }
}

// 患者数据
const patientData = reactive({
  chiefComplaint: '',
  vitalSigns: {
    bloodPressure: '',
    heartRate: undefined as number | undefined,
    temperature: undefined as number | undefined,
    respiratoryRate: undefined as number | undefined,
    oxygenSaturation: undefined as number | undefined
  },
  medicalHistory: ''
})

// 症状文本（用于输入）
const symptomsText = ref('')

// 分诊结果
const triageResult = ref<TriageResult | null>(null)
const isProcessing = ref(false)
const validationWarning = ref('')

// 医生反馈
const doctorFeedback = reactive<DoctorFeedback>({
  comment: '',
  accuracy: 3,
  timestamp: ''
})

// 系统指标
const systemMetrics = reactive<SystemMetrics>({
  responseTime: 150,
  processingSpeed: 10,
  accuracy: 0.85,
  systemStatus: '正常',
  memoryUsage: 45,
  cpuUsage: 30
})

// 计算属性
const canSubmit = computed(() => {
  return patientData.chiefComplaint.trim() !== '' &&
         (patientData.vitalSigns.bloodPressure || 
          patientData.vitalSigns.heartRate !== undefined || 
          patientData.vitalSigns.temperature !== undefined)
})

// 提交分诊请求
const submitTriageRequest = async () => {
  if (!canSubmit.value) {
    ElMessage.warning('请填写必要信息')
    return
  }

  isProcessing.value = true
  validationWarning.value = '' // 清空之前的警告
  
  try {
    // 构建请求数据
    const request: TriageRequest = {
      chiefComplaint: patientData.chiefComplaint,
      symptoms: symptomsText.value ? symptomsText.value.split(/[,，\s]+/).filter(s => s.trim()) : [],
      vitalSigns: patientData.vitalSigns,
      medicalHistory: patientData.medicalHistory,
      textData: patientData.chiefComplaint
    }

    const result = await MedicalRAGService.submitTriageRequest(request)
    triageResult.value = result
    
    // 添加结果合理性检查
    const validationResult = validateTriageResult(result, request)
    if (!validationResult.isValid) {
      validationWarning.value = validationResult.message
      ElMessage.warning(`⚠️ ${validationResult.message}`)
    } else {
      ElMessage.success('分诊分析完成')
    }
  } catch (error: any) {
    console.error('分诊请求失败:', error)
    ElMessage.error(error.message || '分诊分析失败')
  } finally {
    isProcessing.value = false
  }
}

// 验证分诊结果合理性
const validateTriageResult = (result: TriageResult, request: TriageRequest) => {
  const { recommendedDepartment, reasoning } = result.recommendation
  const inputSymptoms = request.symptoms || []
  const chiefComplaint = request.chiefComplaint.toLowerCase()
  
  // 检查头痛患者是否被错误分诊到呼吸科
  if ((chiefComplaint.includes('头痛') || inputSymptoms.some(s => s.includes('头痛'))) && 
      recommendedDepartment.includes('呼吸')) {
    return {
      isValid: false,
      message: '警告：头痛患者被分诊到呼吸内科，建议咨询医生确认'
    }
  }
  
  // 检查推理中是否包含患者未输入的症状
  const reasoningLower = reasoning.toLowerCase()
  const inputText = (request.chiefComplaint + ' ' + inputSymptoms.join(' ')).toLowerCase()
  
  // 常见症状关键词检查
  const symptomKeywords = ['呼吸困难', '胸闷', '胸痛', '心悸', '咳嗽', '咳痰']
  const unexpectedSymptoms = symptomKeywords.filter(symptom => 
    reasoningLower.includes(symptom) && !inputText.includes(symptom)
  )
  
  if (unexpectedSymptoms.length > 0) {
    return {
      isValid: false,
      message: `警告：分析推理中提到了患者未输入的症状（${unexpectedSymptoms.join('、')}），建议咨询医生确认`
    }
  }
  
  // 检查科室与症状的匹配度
  const departmentSymptomMap: Record<string, string[]> = {
    '神经': ['头痛', '头晕', '眩晕', '癫痫', '偏瘫', '麻木'],
    '心血管': ['胸痛', '胸闷', '心悸', '心慌', '血压'],
    '呼吸': ['咳嗽', '咳痰', '呼吸困难', '气短', '哮喘'],
    '消化': ['腹痛', '恶心', '呕吐', '腹泻', '便秘'],
    '内分泌': ['多饮', '多尿', '消瘦', '肥胖', '糖尿病']
  }
  
  const inputSymptomsLower = inputSymptoms.map(s => s.toLowerCase())
  const hasMatchingSymptom = Object.entries(departmentSymptomMap).some(([dept, symptoms]) => {
    if (recommendedDepartment.includes(dept)) {
      return symptoms.some(symptom => 
        inputSymptomsLower.some(inputSymptom => inputSymptom.includes(symptom)) ||
        chiefComplaint.includes(symptom)
      )
    }
    return false
  })
  
  if (!hasMatchingSymptom && inputSymptoms.length > 0) {
    return {
      isValid: false,
      message: '警告：推荐科室与患者症状匹配度较低，建议咨询医生确认'
    }
  }
  
  return { isValid: true, message: '' }
}

// 提交医生反馈
const submitDoctorFeedback = async () => {
  try {
    doctorFeedback.timestamp = new Date().toISOString()
    await MedicalRAGService.submitDoctorFeedback(doctorFeedback)
    ElMessage.success('反馈提交成功')
    resetFeedback()
  } catch (error: any) {
    ElMessage.error('反馈提交失败')
  }
}

// 重置反馈
const resetFeedback = () => {
  doctorFeedback.comment = ''
  doctorFeedback.accuracy = 3
  doctorFeedback.timestamp = ''
}

// 获取优先级类型
const getPriorityType = (priority: number): string => {
  const types: Record<number, string> = {
    0: 'danger',    // Emergency
    1: 'warning',   // Urgent
    2: 'info',      // Routine
    3: 'success'    // NonUrgent
  }
  return types[priority] || 'info'
}

// 获取优先级文本
const getPriorityText = (priority: number): string => {
  const texts: Record<number, string> = {
    0: '急诊',
    1: '紧急',
    2: '常规',
    3: '非紧急'
  }
  return texts[priority] || '未知'
}

// 获取置信度颜色
const getConfidenceColor = (confidence: number): string => {
  if (confidence >= 0.8) return '#67C23A'
  if (confidence >= 0.6) return '#E6A23C'
  return '#F56C6C'
}

// 格式化时间
const formatTime = (timeString: string): string => {
  try {
    const date = new Date(timeString)
    return date.toLocaleString('zh-CN')
  } catch {
    return timeString
  }
}

// 加载系统指标
const loadSystemMetrics = async () => {
  try {
    const metrics = await MedicalRAGService.getSystemMetrics()
    Object.assign(systemMetrics, metrics)
  } catch (error) {
    console.error('加载系统指标失败:', error)
  }
}

// 组件挂载
onMounted(() => {
  initZoom()
  loadSystemMetrics()
})
</script>

<style scoped>
.smart-medical-rag {
  padding: 20px;
  min-height: 100vh;
  background: #f5f7fa;
}

.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  padding: 20px;
  background: white;
  border-radius: 8px;
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

.header h1 {
  margin: 0;
  color: #303133;
}

.zoom-controls {
  display: flex;
  gap: 10px;
}

.main-content {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
  margin-bottom: 20px;
}

.input-section, .result-section {
  background: white;
  padding: 20px;
  border-radius: 8px;
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

.input-section h2, .result-section h2 {
  margin-top: 0;
  margin-bottom: 20px;
  color: #303133;
  border-bottom: 2px solid #409EFF;
  padding-bottom: 10px;
}

.vital-signs {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 15px;
}

.vital-sign-item {
  display: flex;
  align-items: center;
  gap: 8px;
}

.vital-sign-item label {
  min-width: 80px;
  font-weight: 500;
}

.vital-sign-item span {
  color: #606266;
  font-size: 12px;
}

.no-result {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 200px;
}

.triage-result {
  margin-top: 20px;
}

.result-card {
  margin-bottom: 20px;
}

.result-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.result-content {
  line-height: 1.6;
}

.result-content h4 {
  margin: 15px 0 8px 0;
  color: #303133;
  font-size: 14px;
}

.reasoning p {
  background: #f5f7fa;
  padding: 12px;
  border-radius: 4px;
  margin: 0;
}

.confidence {
  display: flex;
  align-items: center;
  gap: 10px;
}

.confidence span {
  font-weight: 500;
  color: #409EFF;
}

.guidelines {
  margin: 15px 0;
}

.guideline-tag {
  margin: 4px;
}

.sources ul {
  margin: 8px 0;
  padding-left: 20px;
}

.sources li {
  margin: 4px 0;
  color: #606266;
}

.processing-info {
  margin-top: 15px;
  padding-top: 15px;
  border-top: 1px solid #EBEEF5;
}

.processing-info p {
  margin: 8px 0;
  display: flex;
  align-items: center;
  gap: 8px;
}

.warning-section {
  margin-bottom: 20px;
}

.feedback-section {
  background: white;
  padding: 20px;
  border-radius: 8px;
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
  margin-bottom: 20px;
}

.feedback-section h2 {
  margin-top: 0;
  margin-bottom: 20px;
  color: #303133;
  border-bottom: 2px solid #409EFF;
  padding-bottom: 10px;
}

.metrics-section {
  background: white;
  padding: 20px;
  border-radius: 8px;
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

.metrics-section h2 {
  margin-top: 0;
  margin-bottom: 20px;
  color: #303133;
  border-bottom: 2px solid #409EFF;
  padding-bottom: 10px;
}

.metrics-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 15px;
}

.metric-card {
  background: #f5f7fa;
  padding: 15px;
  border-radius: 6px;
  text-align: center;
  border-left: 4px solid #409EFF;
}

.metric-card h3 {
  margin: 0 0 8px 0;
  font-size: 14px;
  color: #606266;
}

.metric-card p {
  margin: 0;
  font-size: 18px;
  font-weight: 600;
  color: #303133;
}

@media (max-width: 768px) {
  .main-content {
    grid-template-columns: 1fr;
  }
  
  .vital-signs {
    grid-template-columns: 1fr;
  }
  
  .metrics-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}
</style> 